package com.fz.utils;

import com.aliyuncs.CommonRequest;
import com.aliyuncs.CommonResponse;
import com.aliyuncs.DefaultAcsClient;
import com.aliyuncs.IAcsClient;
import com.aliyuncs.http.MethodType;
import com.aliyuncs.profile.DefaultProfile;
import com.fz.common.ResponseEntity;
import com.fz.common.ResultCode;
import com.fz.common.StatusCode;
import com.fz.entity.msg.Msg;
import com.fz.mapper.msg.MsgMapper;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Component;
import javax.annotation.Resource;
import java.time.LocalDateTime;
import java.util.Map;
import java.util.Random;
@SuppressWarnings("unchecked")
@Component
public class SendMsgUtils {

    private final static Logger logger = LoggerFactory.getLogger(SendMsgUtils.class);

    @Resource
    private MsgMapper msgMapper;
    @Resource
    private RedisUtil redisUtil;

    public static String regionId = PropertyUtil.getProperties("msg.regionId");

    public static String accessKeyId = PropertyUtil.getProperties("msg.accessKeyId");

    public static String secret = PropertyUtil.getProperties("msg.secret");

    public static String domain = PropertyUtil.getProperties("msg.domain");

    public static String version = PropertyUtil.getProperties("msg.version");

    public static String action = PropertyUtil.getProperties("msg.action");

    public static String signName = PropertyUtil.getProperties("msg.signName");

    //#短信验证码模板code
    public static String smsCode = PropertyUtil.getProperties("msgtemp.sms_code");

    //企业用户关联到期提醒，短信授权到期提醒模板code
    public static String relaexpireCode = PropertyUtil.getProperties("msgtemp.relaexpire_code");
    //企业证件到期提醒模板code
    public static String companydueCode = PropertyUtil.getProperties("msgtemp.companydue_code");
    //个人证件到期提醒模板code
    public static String employeedueCode = PropertyUtil.getProperties("msgtemp.employeedue_code");

    //企业备案到期提醒模板code
    public static String recorddueCode = PropertyUtil.getProperties("msgtemp.recorddue_code");;
    /**
     * @方法描述: 实际外部调用发送短信接口
     * @参数:  mobilePhone 手机号   key redis中存的key  time 表示在redis中存在的时长 type 表示是那种类型的发送验证码
     * @返回值:
     * @创建人: I am God
     * @创建时间:: 2021/3/11
     */
    //因为不同的验证码,存在不同的key，例如注册验证码的key与修改密码的短信验证码的key不同,可能存在不同的有效时间
    public ResponseEntity sendSms(String mobilePhone,String key,long time,int type) throws Exception {
        //获取到短信验证码
        String msgCode = "";
        ResponseEntity responseEntity = sendMsgCodeAli(mobilePhone);
        if(responseEntity.getStatus() == StatusCode.OK) {
            msgCode = (String) responseEntity.getData();
        }
        //将验证码存入redis当中
        redisUtil.set(key,msgCode,time);
        //保存短信记录
        Msg msg = new Msg();
        msg.setContent(msgCode);
        msg.setCreateTime(LocalDateTime.now());
        msg.setMobilePhone(mobilePhone);
        msg.setModeType(smsCode);
        msg.setType(type);
        msgMapper.insert(msg);
        return ResponseEntity.buildSuccess(null);
    }



    /**
     * @方法描述:  阿里云短信发送验证码
     * @参数:
     * @返回值:
     * @创建人: I am God
     * @创建时间:: 2021/3/11
     */
    private ResponseEntity sendMsgCodeAli(String mobilePhone) throws Exception{
        //生成六位数字
        String code = getDynCode();
        try{
            //阿里云配置
            DefaultProfile profile = DefaultProfile.getProfile(regionId, accessKeyId, secret);
            IAcsClient client = new DefaultAcsClient(profile);
            CommonRequest request = new CommonRequest();
            request.setMethod(MethodType.POST);
            request.setDomain(domain);
            request.setVersion(version);
            request.setAction(action);
            request.putQueryParameter("RegionId", regionId);
            //接受短信验证码的手机号
            request.putQueryParameter("PhoneNumbers", mobilePhone);
            // 短信签名名称。请在控制台签名管理页面签名名称一列查看（必须是已添加、并通过审核的短信签名）。
            request.putQueryParameter("SignName", signName);
            // 短信模板ID
            request.putQueryParameter("TemplateCode", smsCode);
            request.putQueryParameter("TemplateParam", "{\"code\":\"" + code + "\"}");
            CommonResponse response = client.getCommonResponse(request);
            Map<String,Object> map = JacksonUtils.string2Obj(response.getData(),Map.class);
            // 判断是否发送成功
            if (map.get("Code") == null || !map.get("Code").equals("OK")) {
                logger.error("发送短信失败,手机号:{},错误码:{},错误信息:{}", mobilePhone, ResultCode.ERROR.getResultCode().toString(), map.get("Message").toString());
                return ResponseEntity.build(ResultCode.ERROR.getResultCode(),map.get("Message").toString());
            }
            //短信频繁发送
            if("触发小时级流控Permits:5".equals(map.get("Message").toString())){
                return ResponseEntity.build(ResultCode.MSG_OFTEN_ERROR.getResultCode(),ResultCode.MSG_OFTEN_ERROR.getMessage());
            }
        }catch (Exception e){
            logger.error("发送短信验证码异常:"+e);
        }
        return ResponseEntity.buildSuccess(code);
    }

    /**
     * @方法描述: 阿里云发送短信内容
     * @参数:  mobilePhone 手机号  templateCode 模板编号 map 短信参数
     * @返回值:
     * @创建人: I am God
     * @创建时间:: 2021/3/11
     */
    public ResponseEntity sendMsgContent(String mobilePhone, String templateCode, Map<String,Object> mapParam, int type){
        try {
            DefaultProfile profile = DefaultProfile.getProfile(regionId, accessKeyId, secret);
            IAcsClient client = new DefaultAcsClient(profile);
            CommonRequest request = new CommonRequest();
            request.setSysMethod(MethodType.POST);
            request.setSysDomain(domain);
            request.setSysVersion(version);
            request.setSysAction(action);
            request.putQueryParameter("RegionId", regionId);
            request.putQueryParameter("PhoneNumbers", mobilePhone);
            //签名
            request.putQueryParameter("SignName", signName);
            //模板代码
            request.putQueryParameter("TemplateCode", templateCode);
            //用户定义的短信内容
            request.putQueryParameter("TemplateParam", JacksonUtils.obj2String(mapParam));
            CommonResponse response = client.getCommonResponse(request);
            Map<String,Object> map = JacksonUtils.string2Obj(response.getData(),Map.class);
            // 判断是否发送成功
            if (map.get("Code") == null || !map.get("Code").equals("OK")) {
                logger.error("发送短信失败,手机号:{},错误码:{},错误信息:{}", mobilePhone, ResultCode.ERROR.getResultCode().toString(), map.get("Message").toString());
                return ResponseEntity.build(ResultCode.ERROR.getResultCode(),map.get("Message").toString());
            }
            //保存短信记录
            Msg msg = new Msg();
            msg.setContent(JacksonUtils.obj2String(mapParam));
            msg.setCreateTime(LocalDateTime.now());
            msg.setMobilePhone(mobilePhone);
            msg.setModeType(templateCode);
            msg.setType(type);
            msgMapper.insert(msg);
        }catch (Exception e){
            logger.error("发送短信内容异常:"+e);
        }
        return ResponseEntity.buildSuccess(null);
    }

    /**
     * @方法描述: 生成六位数字（验证码）
     * @参数:
     * @返回值:
     * @创建人: I am God
     * @创建时间:: 2021/3/11
     */
    public static String getDynCode(){
        String str ="";
        char[] a = new char[10];
        char a1 ='0';
        for(int i=0;i<a.length;i++){
            a[i]=a1++;
        }
        Random rand = new Random();
        for(int i =0;i<6;i++){
            str =str+String.valueOf(a[rand.nextInt(10)]);
        }
        return str;
    }
}
